//
// Created by ms on 2025/10/21.
//

#ifndef _COMMANDER_H
#define _COMMANDER_H

#include "stdint.h"
#include <list>

class Command;

class Commander {
public:
    explicit Commander(const char *soh = "*", const char *midl = "=", const char *eol = "\n");

    ~Commander() = default;

    int addCommand(Command *command);
    Command *searchCommand(const char *id);
    Command *parse(char *frame);
    Command *parse(uint8_t *data, uint16_t length);
    size_t getResult(uint8_t *data, uint16_t length);

    size_t getResult(char *data, uint16_t length) { return getResult((uint8_t *) data, length); }

    char *getResultBuffer() { return result_buffer; }

protected:
    void pushCommandResultFrame(Command *cmd);

private:
    const char *_soh;
    const char *_midl;
    const char *_eol;
    uint8_t    soh_len;
    uint8_t    midl_len;
    uint8_t    eol_len;

    char wildcards[32]; // wildcards char
    char data_buffer[128];
    char result_buffer[256];

    std::list<Command *> command_list;
};


class Command {
public:
    typedef void (*Callback_t)(Command *cmd);

public:
    Command(const char *_id, Commander *_cmder, Callback_t cb, const char *_def_ret = "ok") :
            id(_id), cmder(_cmder), callback(cb), def_ret(_def_ret) {

        cmder->addCommand(this);
    }

    ~Command() {
        id       = nullptr;
        callback = nullptr;
    }

    int pushResult(const char *fmt, ...) const;

public:
    const char *id;
    const char *def_ret;
    Commander  *cmder;

    char *data     = nullptr;
    char *ret_data = nullptr;

    Callback_t callback = nullptr;
};

#endif //_COMMANDER_H
